/* eslint-disable indent */
'use strict'

const Controller = require('egg').Controller
const dayjs = require('dayjs')
const fs = require('fs')
const path = require('path')
const pump = require('mz-modules/pump')

/**
 * @controller Upload 文件上传模块
 */
class UploadController extends Controller {

    // file方式上传
    async file() {
        const { service, helper, request } = this.ctx
        try {
            // 获取上传的文件
            const file = request.files[0]
            const filename = file.filename // 文件名
            const new_filename = dayjs().format('YYYYMMDDHHmmss') + '_' + filename // 新的文件名
            const file_path = file.filepath // 原始文件路径
            const file_ext = path.extname(filename) // 文件扩展名
            const target_path = path.join(this.config.multipart.baseDir, `public/uploads/${dayjs().format('YYYYMMDD')}`) // 存放路径
            const target = path.join(target_path, new_filename) // 文件路径

            // 校验文件类型
            if (!this.config.multipart.fileExtensions.includes(file_ext)) {
                helper.error(null, '文件类型不合法')
                return
            }

            // 检测创建目标目录
            if (!fs.existsSync(target_path)) {
                fs.mkdirSync(target_path, { recursive: true })
            }

            // 检测删除目标文件
            if (fs.existsSync(target)) {
                fs.unlinkSync(target)
            }

            // 保存文件
            await this.ctx.cleanupRequestFiles() // 清理临时文件
            await fs.writeFileSync(target, file.filepath, 'binary') // 写入文件
            await this.ctx.cleanupRequestFiles() // 清理临时文件

            this.ctx.body = {
                code: 0,
                message: 'SUCCESS',
                data: {
                    filename,
                    filepath: target
                }
            }
        } catch (error) {
            console.log('错误', error)
            await this.ctx.cleanupRequestFiles() // 清理临时文件
            helper.error(null, error)
        }
    }

    /**
       * @summary 文件上传
       * @description stream模式
       * @router post /v1/upload/stream
       * @request formData file *file
       * @request header string authorization token值
       */
    async stream() {
        const { service, helper, request } = this.ctx
        try {
            // 获取上传的文件
            const stream = await this.ctx.getFileStream()
            const filename = stream.filename // 文件名
            const file_ext = path.extname(filename)

            // 生成新的文件名
            const new_filename = dayjs().format('YYYYMMDDHHmmss') + '_' + filename // 新的文件名
            const target_path = path.join(this.config.multipart.baseDir, `public/uploads/${dayjs().format('YYYYMMDD')}`) // 存放路径
            const target = path.join(target_path, new_filename) // 文件路径
            const ret_url = `/public/uploads/${dayjs().format('YYYYMMDD')}/${new_filename}` // 返回的URL

            // 校验文件类型
            if (!this.config.multipart.fileExtensions.includes(file_ext)) {
                helper.error(null, '文件类型不合法')
                return
            }

            // 检测创建目标目录
            if (!fs.existsSync(target_path)) {
                fs.mkdirSync(target_path, { recursive: true })
            }

            // 检测删除目标文件
            if (fs.existsSync(target)) {
                fs.unlinkSync(target)
            }

            // 保存文件
            const writeStream = await fs.createWriteStream(target)
            await pump(stream, writeStream)

            this.ctx.body = {
                code: 0,
                message: 'SUCCESS',
                data: {
                    url: ret_url,
                    fields: stream.fields
                }
            }
        } catch (error) {
            console.log('错误', error)
            helper.error(null, error)
        }
    }
}

module.exports = UploadController

